package cn.iocoder.yudao.module.hs.netty;

import cn.hutool.extra.spring.SpringUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

@Slf4j
public class ReadHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        super.channelRead(ctx, msg);

        RedisTemplate redisTemplate = (RedisTemplate) SpringUtil.getApplicationContext().getBean("redisTemplate");
        ValueOperations<String, RFIDData> valueOps = redisTemplate.opsForValue();
        ValueOperations<String, RFIDData> valueLastOps = redisTemplate.opsForValue();
        SetOperations<String, String> setOps = redisTemplate.opsForSet();
        SetOperations<String, String> setLastOps = redisTemplate.opsForSet();

        String[] split = String.valueOf(msg).split("\\r\\n");
        for (String rfidMsg : split) {
            if (rfidMsg.length() != 40) {
                continue;
            }
            // 截取设备ID
            String deviceId = rfidMsg.substring(1, 9);
            // 注册基站通道到 Map 中
            if (!Transmission.getChannelMap().containsKey(deviceId)) {
                Transmission.addChannel(deviceId, ctx.channel());
                int size = Transmission.getChannelMap().size();
                log.info("第 {} 台基站连接成功：{}", size, deviceId);
            }
            // 截取rfid编码
            String rfidCode = rfidMsg.substring(21, 31);
            if ("0000000000".equals(rfidCode)) {
                // 更新基站缓存
                Transmission.addChannel(deviceId, ctx.channel());
                continue;
            }

            // 截取电量标识位
            Integer isLow = "A".equals(rfidMsg.substring(31, 32)) ? 0 : 1;
            // 截取rssi
            Integer rssi = Integer.parseInt(rfidMsg.substring(36, 37), 16);
            // 时间
            String time = rfidMsg.substring(9, 20);

            RFIDData rfidData = new RFIDData();
            rfidData.setDeviceId(deviceId);
            rfidData.setRfidCode(rfidCode);
            rfidData.setReportTime(LocalDateTime.now());
            rfidData.setIsLow(isLow);
            rfidData.setRssi(rssi);

            // 将标签上报数据存储到 Redis
            // 存储明细
            String rfidDataKey = "RFID:" + rfidCode +  ":" + time;
            valueOps.set(rfidDataKey, rfidData, 2, TimeUnit.MINUTES);

            // 同一个RFID仅存储最新的一条
            String rfidDataLastKey = "RFID:" + rfidCode;
            valueLastOps.set(rfidDataLastKey, rfidData,2, TimeUnit.MINUTES);
            // 将标签对象对应的key保存到 LAST_RFID_LIST 中
            setLastOps.add("LAST_RFID_LIST", rfidDataLastKey);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
    }
}
